using LiteDB;
using System;
using System.IO;
using System.Linq;
using DidaManager.Log;
using Newtonsoft.Json.Linq;
using System.Text;

namespace LiteDb
{
    /// <summary>
    /// 主数据库管理器 - 专门处理main.db的分组和设备信息
    /// </summary>
    public class MainDbManager : IDisposable
    {
        private readonly LiteDatabase _mainDb;
        public GroupRepository GroupRepo { get; }
        public GroupDeviceRepository GroupDeviceRepo { get; }

        // 设备数据库操作回调
        public Func<int, object>? OnDeviceAdded { get; set; }
        public Func<int, int,object>? OnDeviceDeleted { get; set; }
        // 分组数据库操作回调
        public Func<int, object>? OnGroupDeleted { get; set; }
        public Func<object, string, object>? OnExportGroupDevice { get; set; }
        public Func<object, int, object>? OnImportGroupDevice { get; set; }

        public MainDbManager(string mainDbPath)
        {
            // 确保数据库文件所在目录存在
            var directory = Path.GetDirectoryName(mainDbPath);
            if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
                LogManager.Info($"创建主数据库目录: {directory}");
            }

            var connectionString = $"Filename={mainDbPath};Connection=shared";
            _mainDb = new LiteDatabase(connectionString);
            
            GroupRepo = new GroupRepository(_mainDb);
            GroupDeviceRepo = new GroupDeviceRepository(_mainDb);
            
            // 初始化索引
            _mainDb.GetCollection<Group>(Group.CollectionName).EnsureIndex(x => x.Id);
            _mainDb.GetCollection<GroupDevice>(GroupDevice.CollectionName).EnsureIndex(x => x.Id);
            _mainDb.GetCollection<GroupDevice>(GroupDevice.CollectionName).EnsureIndex(x => x.GroupId);
            
            LogManager.Info($"主数据库已连接: {mainDbPath}");
        }

        // Group 操作
        public object AddGroup(object param) => GroupRepo.Insert(param);
        public object GetGroup(object param) => GroupRepo.FindById(param);
        public object GetAllGroups(object? param = null) => GroupRepo.FindAll();
        public object GetGroupsByGroupId(object param) => GroupRepo.GetByGroupId(param);
        public object UpdateGroup(object param) => GroupRepo.Update(param);
        
        public object DeleteGroup(object param)
        {
            try
            {
                int groupId = Convert.ToInt32(param);
                
                // 先获取分组信息（用于返回结果）
                var groupResult = GroupRepo.FindById(param);
                string groupName = "未知分组";
                
                if (groupResult is ApiResponse groupApiResponse && groupApiResponse.IsSuccess)
                {
                    try
                    {
                        if (groupApiResponse.data != null)
                        {
                            dynamic dynData = groupApiResponse.data;
                            groupName = dynData?.name ?? "未知分组";
                        }
                    }
                    catch { }
                }
                
                // 调用原有的Group.cs接口删除记录
                var result = GroupRepo.Delete(param);
                
                // 如果删除成功，触发分组数据库文件夹删除回调
                if (result is ApiResponse deleteApiResponse && deleteApiResponse.IsSuccess)
                {
                    try
                    {
                        var callbackResult = OnGroupDeleted?.Invoke(groupId);
                        LogManager.Info($"分组删除回调执行完成，结果: {callbackResult}");
                        
                        // 返回增强的结果
                        return ApiResponse.Success(new { 
                            deletedGroup = groupName,
                            groupId = groupId,
                            callbackResult = callbackResult
                        }, "删除分组成功，已清理相关数据库文件");
                    }
                    catch (Exception ex)
                    {
                        LogManager.Error("触发分组删除回调时出错", ex);
                    }
                }
                
                return result;
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"删除分组失败: {ex.Message}");
            }
        }
        
        public object GetGroupTreeWithDevices(object param) => GroupRepo.GetGroupTreeWithDevices();

        // GroupDevice 操作（增强版，处理设备数据库生命周期）
        public object AddGroupDevice(object param)
        {
            // 调用原有的Group.cs接口
            var result = GroupDeviceRepo.Insert(param);
            // 如果插入成功，触发设备数据库创建回调
            if (result is ApiResponse apiResponse && apiResponse.IsSuccess)
            {
                try
                {
                    // 从ApiResponse中提取deviceId
                    if (apiResponse.data != null)
                    {
                        dynamic dynData = apiResponse.data;
                        var deviceId = (int)dynData;
                        var callbackResult = OnDeviceAdded?.Invoke(deviceId);
                        LogManager.Info($"设备添加回调执行完成，设备ID: {deviceId}，结果: {callbackResult}");
                    }
                }
                catch (Exception ex)
                {
                    LogManager.Error("触发设备创建回调时出错", ex);
                }
            }
            
            return result;
        }

        public object GetGroupDevice(object param) => GroupDeviceRepo.FindById(param);
        public object GetAllGroupDevices(object? param = null) => GroupDeviceRepo.FindAll();
        public object GetGroupDevicesByGroupId(object param) => GroupDeviceRepo.GetByGroupId(param);
        public object UpdateGroupDevice(object param) => GroupDeviceRepo.Update(param);

        public object DeleteGroupDevice(object param)
        {
            try
            {
                int deviceId = Convert.ToInt32(param);
                
                // 先获取设备信息（用于返回结果）
                var deviceResult = GroupDeviceRepo.FindById(param);
                string deviceName = "未知设备";
                
                if (deviceResult is ApiResponse deviceApiResponse && deviceApiResponse.IsSuccess)
                {
                    try
                    {
                        if (deviceApiResponse.data != null)
                        {
                            dynamic dynData = deviceApiResponse.data;
                            deviceName = dynData?.name ?? "未知设备";
                        }
                    }
                    catch { }
                }

                deviceResult = GroupDeviceRepo.FindGroupById(param);
                var resultData = deviceResult is ApiResponse dr && dr.IsSuccess ? dr.data : null;
                int groupId = Convert.ToInt32(resultData);
                // 调用原有的Group.cs接口删除记录
                var result = GroupDeviceRepo.Delete(param);
                
                // 如果删除成功，触发设备数据库删除回调
                if (result is ApiResponse deleteApiResponse && deleteApiResponse.IsSuccess)
                {
                    try
                    {
                        var callbackResult = OnDeviceDeleted?.Invoke(deviceId, groupId);
                        LogManager.Info($"设备删除回调执行完成，设备ID: {deviceId}，结果: {callbackResult}");
                        
                        // 返回增强的结果
                        return ApiResponse.Success(new { 
                            deletedDevice = deviceName,
                            callbackResult = callbackResult
                        }, "删除成功");
                    }
                    catch (Exception ex)
                    {
                        LogManager.Error("触发设备删除回调时出错", ex);
                    }
                }
                
                return result;
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"删除失败: {ex.Message}");
            }
        }
        
        public object ExportGroupDevice(object param)
        {
            try
            {
                //GetGroup 获取group信息，并导出到文件，再触发回调生成db
                //获取分组id
                if (param == null)
                {
                    return ApiResponse.Fail("参数不能为空");
                }
                var jsonParam = JObject.Parse(param.ToString() ?? "");
                var deviceId = jsonParam["deviceId"]?.ToString();
                if (string.IsNullOrEmpty(deviceId))
                {
                    return ApiResponse.Fail("分组ID不能为空");
                }
                var group = GroupDeviceRepo.FindById(deviceId);
                if (group is ApiResponse groupApiResponse && groupApiResponse.IsSuccess)
                {
                    string groupJson = groupApiResponse.data?.ToString() ?? "";
                    var callbackResult = OnExportGroupDevice?.Invoke(param, groupJson);
                    LogManager.Info($"导出分组设备回调执行完成，结果: {callbackResult}");
                    
                    // 如果回调返回了失败结果，直接返回
                    if (callbackResult is ApiResponse callbackApiResponse && !callbackApiResponse.IsSuccess)
                    {
                        return callbackResult;
                    }
                    
                    return ApiResponse.Success(new { callbackResult = callbackResult }, "导出成功");
                }
                else
                {
                    return ApiResponse.Fail("导出失败");
                }
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"导出失败: {ex.Message}");
            }
        }

        public object ImportGroupDevice(object param)
        {
            try
            {
                // 获取分组设备id和导出文件夹路径
                if (param == null)
                {
                    return ApiResponse.Fail("参数不能为空");
                }
                var jsonParam = JObject.Parse(param.ToString() ?? "");
                var groupId = jsonParam["groupDeviceId"]?.ToString();
                var importFolder = jsonParam["importFolder"]?.ToString();

                if (string.IsNullOrEmpty(groupId) || string.IsNullOrEmpty(importFolder))
                {
                    return ApiResponse.Fail("参数不能为空");
                }

                // 检查importFolder是否存在
                if (!Directory.Exists(importFolder))
                {
                    return ApiResponse.Fail("导入文件夹不存在");
                }

                // 1.检查importFolder是否存在*.json文件
                var jsonFiles = Directory.GetFiles(importFolder, "*.json");
                if (jsonFiles.Length == 0)
                {
                    return ApiResponse.Fail("导入文件夹不存在*.json文件");
                }
                // 2.检查mportFolder中的*.db文件
                var dbFiles = Directory.GetFiles(importFolder, "*.db");
                if (dbFiles.Length == 0)
                {
                    return ApiResponse.Fail("导入文件夹不存在*.db文件");
                }
                // 3.判断*.json和*.db文件的名称是否一致
                foreach (var jsonFileTmp in jsonFiles)
                {
                    var dbFile = Path.Combine(importFolder, Path.GetFileNameWithoutExtension(jsonFileTmp) + ".db");
                    if (!File.Exists(dbFile))
                    {
                        return ApiResponse.Fail("导入文件夹中的*.json和*.db文件名称不一致");
                    }
                }
                // 4.找到*.json和*.db文件的名称是一致的文件
                var jsonFile = jsonFiles.FirstOrDefault(file => dbFiles.Any(dbFile => Path.GetFileNameWithoutExtension(file) == Path.GetFileNameWithoutExtension(dbFile)));
                if (jsonFile == null)
                {
                    return ApiResponse.Fail("导入文件夹中的*.json和*.db文件名称不一致");
                }
                // 5.获取到存在的jsonFile
                var jsonContent = File.ReadAllText(jsonFile);// 获取jsonFile的内容
                // groupId转为整形
                int groupIdInt = Convert.ToInt32(groupId);
                var result = GroupDeviceRepo.InsertTemp(jsonContent,groupIdInt);
                if (result is ApiResponse apiResponse && apiResponse.IsSuccess)
                {
                    if (apiResponse.data != null)
                    {
                        dynamic dynData = apiResponse.data;
                        var deviceId = (int)dynData;
                        var addCallbackResult = OnDeviceAdded?.Invoke(deviceId);
                        var importCallbackResult = OnImportGroupDevice?.Invoke(param, deviceId);
                        LogManager.Info($"设备添加回调结果: {addCallbackResult}，导入回调结果: {importCallbackResult}");
                        return ApiResponse.Success(new { 
                            deviceId = deviceId,
                            addCallbackResult = addCallbackResult,
                            importCallbackResult = importCallbackResult
                        }, "导入成功");
                    }
                }
                else
                {
                    return result;
                }
                return ApiResponse.Success("导入成功");
            }
            catch (Exception ex)
            {
                return ApiResponse.Fail($"导入失败: {ex.Message}");
            }
        }

        public void Dispose()
        {
            _mainDb?.Dispose();
        }
    }
}

